/*
 * Copyright 2010 Piotr Buda
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package li.buda.cqflex.commandbus {

/**
 * The command bus is the entry point from the user interface into the domain part of the application.
 * The UI sends commands to the bus and then the bus routes these commands
 * to subscribed command handlers.
 * @see li.buda.cqflex.commandbus.Command
 * @see li.buda.cqflex.commandbus.CommandHandler
 * @author Piotr Buda
 * @since 0.1
 */
public interface CommandBus {
    /**
     * Publish <code>command</code> to the bus. If there is a command handler subscribed to this command type
     * it will be retrieved and executed. If not, an error is raised.
     * @param command <code>Command</code> instance to publish
     * @throws NoCommandHandlerError if no command handler for this command is found
     */
    function publish(command:Command):void;

    /**
     * Subscribe the given <code>commandHandler</code> as the handler for all commands
     * of type <code>commandType</code>
     * The <code>command</code> argument must be a <code>Class</code> instance that
     * implements the <code>Command</code> interface.
     * <p/>
     * Implementations may decide whether there can be only one <code>commandHandler</code>
     * for each type of <code>Command</code> or more.
     * @param commandType Type of the command
     * @param commandHandler <code>CommandHandler</code> instance that will handle <code>commandType</code> commands
     */
    function subscribe(commandType:Class, commandHandler:CommandHandler):void;

    /**
     * Unsubscribes the given <code>commandHandler</code> from the <code>commandType</code> commands.
     * <p/>
     * The <code>commandHandler</code> argument is optional, because if implementation allows for only
     * one command handler per command, it isn't necessary to specify the command handler.
     * @param commandType Type of the command
     * @param commandHandler command handler to unsubscribe
     */
    function unsubscribe(commandType:Class, commandHandler:CommandHandler = null):void;
}
}